package com.cloud.wms.ui.sort.presenter;


import android.text.TextUtils;

import com.cloud.core.base.BaseRxPresenter;
import com.cloud.core.http.error.ApiException;
import com.cloud.core.utils.MessageCreator;
import com.cloud.core.utils.TimeUtils;
import com.cloud.wms.app.FineExApplication;
import com.cloud.wms.entity.ContainerEntity;
import com.cloud.wms.entity.Page;
import com.cloud.wms.http.Params;
import com.cloud.wms.http.observer.LoadingObserver;
import com.cloud.wms.http.observer.ResponseWrapper;
import com.cloud.wms.tools.PageHelper;
import com.cloud.wms.tools.RxUtils;
import com.cloud.wms.tools.TaskHelper;
import com.cloud.wms.ui.group.entity.BatchCommodityEntity;
import com.cloud.wms.ui.main.entity.CommodityEntity;
import com.cloud.wms.ui.main.entity.RemoteEntity;
import com.cloud.wms.ui.main.entity.TaskEntity;
import com.cloud.wms.ui.main.entity.UserEntity;
import com.cloud.wms.ui.sort.contract.GroupSortContract;
import com.cloud.wms.ui.sort.entity.BatchInfoEntity;
import com.cloud.wms.ui.sort.entity.BindInfoEntity;
import com.cloud.wms.ui.sort.entity.OrderEnum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;

/**
 * @Author:Chen
 * @Date: 2021-01-14 15:51
 * @Description: 清点
 */
public class GroupSortPresenter extends BaseRxPresenter<GroupSortContract.View> implements GroupSortContract.Presenter {
    public static final int BATCH_LIST = 0x100;

    public static final int BIND_CONTAINER = 0x101;

    public static final int SORT_COMMODITY = 0x102;

    public static final int SUBMIT_SORT = 0x103;

    public static final int SORT_DETAIL = 0x104;

    public static final int SORT_POS = 0x109;

    public static final int CHECK_BIND_CONTAINER = 0x105;

    public static final int SUBMIT_COLLECT = 0x106;

    public static final int SORT_COMPLETE = 0x107;

    public static final int TASK = 0x108;

    @Inject
    public GroupSortPresenter() {

    }

    /**
     * 检测波次是否已绑定容器
     *
     * @param billId
     */
    @Override
    public void checkBindContainer(long billId) {
        Params params = new Params();
        params.put("BillType", OrderEnum.Batch);
        params.put("BillID", billId);
        params.put("IsGetOrderInfo", false);

        FineExApplication
                .component()
                .http()
                .sortCheckBind(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<ArrayList<BindInfoEntity>>(mView.provideContext()) {
                    @Override
                    public void onSuccess(ArrayList<BindInfoEntity> info) {
                        mView.showContent();
                        mView.onSuccess(MessageCreator.createMessage(info, CHECK_BIND_CONTAINER));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                        mView.showError();
                    }
                });
    }

    /**
     * 加载备货波次列表数据
     *
     * @param batchCode
     */
    @Override
    public void loadBatchList(String batchCode, int page) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        if (!TextUtils.isEmpty(batchCode)) {
            params.put("BatchCode", batchCode);
        }
        params.put("Sorting", "createDate");
        params.put("SkipCount", PageHelper.skipCount(page));
        params.put("MaxResultCount", PageHelper.PAGE_SIZE);
        params.put("BatchTypeID", 4);//1.散单分拣，2.单sku分拣，3.笼车分拣，4.团购分拣  5、团购除备货外
        FineExApplication
                .component()
                .http()
                .sortBatchList(params)
                .map(new ResponseWrapper<>())
                .map(Page::getItems)
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<ArrayList<BatchInfoEntity>>(mView.provideContext()) {
                    @Override
                    public void onSuccess(ArrayList<BatchInfoEntity> info) {
                        if (page == 0) {
                            mView.onSuccess(MessageCreator.createMessage(info, PageHelper.LIST_NEW_DATA));
                        } else {
                            mView.onSuccess(MessageCreator.createMessage(info, PageHelper.LIST_NEXT_DATA));
                        }
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    @Override
    public void receiveTask(long billId, String taskCode) {
        FineExApplication
                .component()
                .http()
                .orderTaskList(billId + "")
                .map(new ResponseWrapper<>())
                .map(RemoteEntity::getItems)
                .flatMap((Function<ArrayList<TaskEntity>, ObservableSource<TaskEntity>>) Observable::fromIterable)
                .filter(taskEntity -> taskEntity.getTaskCode().equalsIgnoreCase(taskCode))
                .toList()
                .toObservable()
                .flatMap((Function<List<TaskEntity>, ObservableSource<TaskEntity>>) taskEntities -> {
                    if (taskEntities == null || taskEntities.isEmpty()) {
                        return Observable.error(new ApiException("暂无可领用任务"));
                    }
                    TaskEntity taskEntity = taskEntities.get(0);
                    Params params = new Params();
                    params.put("TaskID", taskEntity.getTaskID());
                    UserEntity userInfo = FineExApplication.component().loginCache().getUserInfo();
                    params.put("JobStationID", userInfo.getJobStationID());
                    params.put("ProductCategory", userInfo.getProductCategory());
                    params.put("ExecutorID", userInfo.getUserID());
                    return TaskHelper.receiveTask(params,taskEntity);
                })
                .flatMap((Function<TaskEntity, ObservableSource<TaskEntity>>) taskEntity -> {
                    Params params = new Params();
                    params.put("workId", taskEntity.getWorkID());
                    UserEntity userInfo = FineExApplication.component().loginCache().getUserInfo();
                    params.put("executerId", userInfo.getUserID());
                    return TaskHelper.executeTask(params)
                            .map(aVoid -> taskEntity);
                })
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<TaskEntity>(mView.provideContext()) {
                    @Override
                    public void onSuccess(TaskEntity info) {
                        mView.onSuccess(MessageCreator.createMessage(info, TASK));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 检测并绑定容器
     *
     * @param billId
     * @param containerCode
     */
    @Override
    public void bindContainer(long billId, String containerCode) {
        Params params = Params.newInstance(Params.Type.WAREHOUSE);
        params.put("BoxCode", containerCode);
        FineExApplication
                .component()
                .http()
                .checkContainerUseState(params)
                .map(new ResponseWrapper<>())
                .flatMap((Function<ContainerEntity, ObservableSource<Boolean>>) containerEntity -> {
                    ArrayList<HashMap<String, Object>> list = new ArrayList<>();
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("containerID", containerEntity.getContainerID());
                    map.put("orderID", billId);
                    list.add(map);
                    Params paramsBind = Params.newInstance(Params.Type.WAREHOUSE);
                    paramsBind.put("orderType", OrderEnum.Batch.toString());
                    paramsBind.put("lstBox", list);
                    paramsBind.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
                    return FineExApplication
                            .component()
                            .http()
                            .sortBindContainer(paramsBind)
                            .map(new ResponseWrapper<>());
                })
                .flatMap((Function<Boolean, ObservableSource<Object>>) aBoolean -> {
                    if (!aBoolean) return Observable.error(new ApiException("绑定失败，请检查数据！"));
                    return Observable.just(true);
                })
                .map(o -> {
                    BindInfoEntity entity = new BindInfoEntity();
                    entity.setBillID(billId);
                    entity.setContainerCode(containerCode);
                    return entity;
                })
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<BindInfoEntity>(mView.provideContext()) {
                    @Override
                    public void onSuccess(BindInfoEntity info) {
                        mView.onSuccess(MessageCreator.createMessage(info, BIND_CONTAINER));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    @Override
    public void loadSortCommodity(long billId) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        params.put("BatchTypeID", 1);//1:波次 2:订单
        params.put("DetailbillID", billId);

        FineExApplication
                .component()
                .http()
                .sortBatchDetail(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<BatchCommodityEntity>(mView.provideContext()) {
                    @Override
                    public void onSuccess(BatchCommodityEntity info) {
                        if (info.getLitWjx() == null || info.getLitWjx().isEmpty()) {
                            mView.onSuccess(MessageCreator.createMessage(info.getLitWjx(), SORT_COMPLETE));
                        } else {
                            mView.onSuccess(MessageCreator.createMessage(info.getLitWjx(), SORT_COMMODITY));
                        }
                        mView.onSuccess(MessageCreator.createMessage(info.getBatchPos(), SORT_POS));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                        mView.showError();
                    }
                });
    }

    @Override
    public void loadSortDetail(long billId, boolean state) {
        Params params = Params.newInstance(Params.Type.MEMBER);
        params.put("BatchTypeID", 1);//1:波次 2:订单
        params.put("DetailbillID", billId);

        FineExApplication
                .component()
                .http()
                .sortBatchDetail(params)
                .map(new ResponseWrapper<>())
                .map(batchCommodityEntity -> {
                    if (state) {
                        return batchCommodityEntity.getLitYjx();
                    } else {
                        return batchCommodityEntity.getLitWjx();
                    }
                })
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<ArrayList<CommodityEntity>>(mView.provideContext()) {
                    @Override
                    public void onSuccess(ArrayList<CommodityEntity> info) {
                        if (info == null || info.isEmpty()) {
                            mView.showEmpty();
                        } else {
                            mView.onSuccess(MessageCreator.createMessage(info, SORT_DETAIL));
                        }
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                        mView.showError();
                    }
                });
    }

    /**
     * 备货下架确认
     *
     * @param billId
     * @param posId
     * @param commodityId
     * @param amount
     */
    @Override
    public void submitSort(long billId, long posId, long commodityId, int amount, TaskEntity taskEntity, int StockType, long ProductBatchID) {
        UserEntity userEntity = FineExApplication.component().loginCache().getUserInfo();
        Params params = Params.newInstance(Params.Type.MEMBER);
        params.put("billID", billId);
        params.put("posID", posId);
        params.put("commodityID", commodityId);
        params.put("sortAmount", amount);
        params.put("StockType", 1);
        params.put("ProductBatchId", ProductBatchID);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());
        if (taskEntity != null) {
            params.put("workID", taskEntity.getWorkID());
            params.put("beginTime", taskEntity.getBeginTime());
            params.put("completeTime", TimeUtils.getCurrentDateAndTime());
            params.put("productCategory", userEntity.getProductCategory());
            params.put("jobStationID", userEntity.getJobStationID());
            params.put("appKey", taskEntity.getAppKey());
        }
        Observable<Object> observable;
        if (taskEntity != null) {
            observable = FineExApplication
                    .component()
                    .http()
                    .sortGroupTaskConfirm(params)
                    .map(new ResponseWrapper<>());
        } else {
            observable = FineExApplication
                    .component()
                    .http()
                    .sortGroupConfirm(params)
                    .map(new ResponseWrapper<>());
        }
        observable
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, SUBMIT_SORT));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    /**
     * 绑定集货地
     *
     * @param billID
     * @param collectCode
     */
    @Override
    public void submitCollect(String billID, String collectCode) {
        Params params = Params.newInstance(Params.Type.WAREHOUSE);
        List<String> list = new ArrayList<>();
        list.add(billID);
        params.put("lstOrderID", list);
        params.put("containerCode", collectCode);
        params.put("userID", FineExApplication.component().loginCache().getUserInfo().getUserID());

        FineExApplication
                .component()
                .http()
                .confirmBindCollect(params)
                .map(new ResponseWrapper<>())
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, SUBMIT_COLLECT));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }
}
